package com.ahcloud.enhance.curator.configuration;

import com.ahcloud.enhance.curator.exception.ZkClientStartException;
import com.ahcloud.enhance.curator.lock.ZkLock;
import com.ahcloud.enhance.lock.base.ILock;
import com.ahcloud.enhance.lock.base.LockUtils;
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @program: distributedlock-enhance
 * @description:
 * @author: YuKai Fan
 * @create: 2024/4/30 17:15
 **/
@Slf4j
@Configuration
@EnableConfigurationProperties(CuratorProperties.class)
public class CuratorConfiguration {


    @Bean(destroyMethod = "close")
    @ConditionalOnProperty(prefix = "distributed.lock", name = "type", havingValue = "zk")
    public CuratorFramework curatorFramework(CuratorProperties properties) {
        try {
            CuratorFramework client = CuratorFrameworkFactory.newClient(
                    properties.getZkUrls(),
                    properties.getSessionTimeoutMs().intValue(),
                    properties.getConnectionTimeoutMs().intValue(),
                    RetryPolicyFactory.getPolicyByName(properties.getRetryPolicyConfig())
            );
            client.start();
            log.info("Zookeeper Client [CuratorFramework] start succeed");
            return client;
        } catch (Exception e) {
            log.error("Zookeeper Client [CuratorFramework] start failed, reason is {}", Throwables.getStackTraceAsString(e));
            throw new ZkClientStartException("Zookeeper Client [CuratorFramework] start failed");
        }
    }

    @Bean
    @ConditionalOnBean(CuratorFramework.class)
    public ILock zkLock(CuratorFramework client) {
        ZkLock zkLock = new ZkLock(client);
        LockUtils.setLocker(zkLock);
        return zkLock;
    }
}
